﻿using AntUnion.FrameWork.Model.Models;
using AntUnion.FrameWork.Util;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using AntUnion.FrameWork.Web.Service;
using MetaQuotes.MT5WebAPI.Common;
using static MetaQuotes.MT5WebAPI.Common.MTUser;
using AntUnion.FrameWork.Web.Common;
using RM.Common.DotNetEamil;

namespace AntUnion.FrameWork.Web.Areas.Console.Controllers
{
    [Area("Console")]
    public class MT5UsersController : BaseController
    {
        private readonly IWebHostEnvironment _hostingEnv;
        private readonly mtContext _context;
        private readonly SmtpSettings _emailSender;

        public MT5UsersController(mtContext context, IWebHostEnvironment hostingEnv, SmtpSettings emailSender) : base(context, hostingEnv)
        {
            _context = context;
            _hostingEnv = hostingEnv;
            _emailSender = emailSender;
        }

        public IActionResult Index()
        {
            return View();
        }

        #region 账户列表
        /// <summary>
        /// 获取账户列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<JsonResult> GetListJson(int page, int limit, int crmId = 0, int? accountGroup = null, long? tradingAccountNo = null, string MTgroups = "", string server = "", string fullName = "", string registrationTime = "")
        {
            ListResult res = new ListResult();
            try
            {
                var data = from y in _context.Mt5Users
                           join c in _context.CrmUsers on y.CrmId equals c.Id
                           select new
                           {
                               id = y.Id,
                               crmId = y.CrmId,
                               tradingAccount = y.Login,
                               fullName = c.Name,
                               loginName = c.LoginName,
                               accountGroup = c.CrmGroup,
                               accountOwnership = c.LoginName,
                               server = y.Server,
                               state = y.State,
                               accountType = y.Type,
                               email = y.Email,
                               laverage = y.Laverage,
                               balance = (((y.Balance > y.Equity) ? y.Equity : y.Balance) - y.Margin) < 0 ? "0.00" : ((decimal)(((y.Balance > y.Equity) ? y.Equity : y.Balance) - y.Margin)).ToString("#,##0.00"),
                               groups = y.Group,
                               createDate = y.CreateDate,
                               netValue = y.EquityPrevDay == null ? "0.00" : ((decimal)y.EquityPrevDay).ToString("#,##0.00"),//净值???
                               credit = y.Credit == null ? "0.00" : ((decimal)y.Credit).ToString("#,##0.00") //信用额??
                           };

                if (crmId != 0)
                {
                    data = data.Where(k => k.crmId == crmId);
                }
                if (accountGroup != null)
                {
                    data = data.Where(k => k.accountGroup == accountGroup);
                }
                if (!string.IsNullOrEmpty(MTgroups))
                {
                    data = data.Where(k => k.groups == MTgroups);
                }
                if (!string.IsNullOrEmpty(server))
                {
                    data = data.Where(k => k.server == server);
                }
                if (!string.IsNullOrEmpty(fullName))
                {
                    long loginNo = 0;
                    try
                    {
                        loginNo = Convert.ToInt64(fullName);
                    }
                    catch
                    {
                        loginNo = 0;
                    }
                    if (loginNo == 0)
                    {
                        data = data.Where(k => k.fullName.Contains(fullName) || k.loginName.Contains(fullName));
                    }
                    else
                    {
                        data = data.Where(k => k.fullName.Contains(fullName) || k.loginName.Contains(fullName) || k.tradingAccount == loginNo);
                    }
                }
                if (tradingAccountNo != null)
                {
                    data = data.Where(k => k.tradingAccount == tradingAccountNo);
                }
                if (!string.IsNullOrEmpty(registrationTime) && registrationTime.Contains(" - "))
                {
                    string[] registrationTimes = registrationTime.Split(new string[] { " - " }, StringSplitOptions.None);
                    DateTime startTime = Convert.ToDateTime(registrationTimes[0]);
                    DateTime endTime = Convert.ToDateTime(registrationTimes[1]);
                    data = data.Where(k => k.createDate > startTime && k.createDate < endTime);
                }
                if (page == 0 && limit == 0)
                {
                    res.Data = await data.OrderByDescending(k => k.createDate).ToArrayAsync();
                }
                else
                {
                    res.Data = await data.OrderByDescending(k => k.createDate).Skip((page - 1) * limit).Take(limit).ToArrayAsync();
                }
                res.Code = 0;
                res.Count = data.Count();
                return new JsonResult(res);
            }
            catch (Exception ex)
            {
                res.Code = 1;
                res.Msg = ex.Message;
                return new JsonResult(res);
            }
        }
        #endregion

        #region 编辑
        /// <summary>
        /// 编辑信息
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<JsonResult> EditAccountInfo(long Login, string Name, int accountOwnership, string MTgroups, uint? accountGroup, int laverage)
        {
            Result res = new Result();
            try
            {
                Mt5User model = await _context.Mt5Users.FindAsync(Login);
                if (model != null)
                {
                    model.Name = Name;
                    model.CrmId = accountOwnership;
                    model.Group = MTgroups;
                    model.Laverage = laverage;
                    CrmUser crmUser = await _context.CrmUsers.FindAsync(model.CrmId);
                    if (crmUser != null)
                    {
                        crmUser.Name = Name;
                        if (accountGroup != null)
                        {
                            crmUser.CrmGroup = accountGroup;
                        }
                    }
                    bool isUpdate = UpdateMt5UserInfo(model);
                    if (isUpdate)
                    {
                        res.Code = 0;
                        res.Msg = "submitSuccess";
                        res.Data = await _context.SaveChangesAsync();
                    }
                    else
                    {
                        res.Code = 1;
                        res.Msg = "submitFail";
                    }
                }
                else
                {
                    res.Code = 1;
                    res.Msg = "submitFail";
                }
                return new JsonResult(res);
            }
            catch (Exception ex)
            {
                res.Code = 1;
                res.Msg = ex.Message;
                return new JsonResult(res);
            }
        }

        public bool UpdateMt5UserInfo(Mt5User model)
        {
            MT5CommonHelper helper = new MT5CommonHelper();
            MTUser mt1 = new MTUser();
            mt1.Login = (ulong)model.Login;
            mt1.Rights = (MTUser.EnUsersRights.USER_RIGHT_ENABLED | MTUser.EnUsersRights.USER_RIGHT_PASSWORD | MTUser.EnUsersRights.USER_RIGHT_TRAILING | MTUser.EnUsersRights.USER_RIGHT_REPORTS);
            mt1.Group = model.Group.Replace("\\\\", "\\");
            mt1.Name = model.Name;
            mt1.Company = model.Company;
            if (model.Language != null)
            {
                mt1.Language = (uint)model.Language;
            }
            if (model.Laverage != null)
            {
                mt1.Leverage = (uint)model.Laverage;
            }
            mt1.Country = model.Country;
            mt1.City = model.City;
            mt1.State = model.State;
            mt1.ZIPCode = model.Zipcode;
            mt1.Address = model.Address;
            mt1.Phone = model.Phone;
            mt1.Email = model.Email;
            mt1.ID = model.Id;
            mt1.Status = model.Status;
            mt1.Comment = model.Comment;
            if (model.Color != null)
            {
                mt1.Color = (uint)model.Color;
            }
            mt1.Account = model.Account;
            if (model.Agent != null)
            {
                mt1.Agent = (ulong)model.Agent;
            }
            MTUser mt2 = new MTUser();
            return helper.UpdateUser(mt1, out mt2);
        }
        #endregion

        #region 查看账户详情
        public async Task<IActionResult> MT5AccountInfo(long id)
        {
            Mt5User mt5User = await _context.Mt5Users.FindAsync(id);
            if (mt5User == null)
            {
                return NotFound();
            }
            ViewBag.balance = (((mt5User.Balance > mt5User.Equity) ? mt5User.Equity : mt5User.Balance) - mt5User.Margin) < 0 ? "0.00" : ((decimal)(((mt5User.Balance > mt5User.Equity) ? mt5User.Equity : mt5User.Balance) - mt5User.Margin)).ToString("#,##0.00");
            CrmUser crmUser = _context.CrmUsers.FirstOrDefault(k => k.Id == mt5User.CrmId);
            if (crmUser != null)
            {
                ViewBag.crmUser = crmUser.Name;
                ViewBag.crmGroup = crmUser.CrmGroup;
            }
            else
            {
                ViewBag.crmUser = null;
                ViewBag.crmGroup = null;
            }
            return View(mt5User);
        }
        #endregion

        #region 获取MT分组
        [HttpGet]
        public async Task<JsonResult> GetMTGroupListJson()
        {
            ListResult res = new ListResult();
            try
            {
                var data = from y in _context.Mt5Groups
                           select new
                           {
                               id = y.Mt5ServerId,
                               groupName = y.Group,
                               startLogin = y.StartLogin,
                               endLogin = y.EndLogin,
                               createDate = y.CreateDate
                           };
                res.Count = data.Count();
                res.Data = await data.OrderByDescending(k => k.createDate).ToArrayAsync();
                res.Code = 0;
                return new JsonResult(res);
            }
            catch (Exception ex)
            {
                res.Code = 1;
                res.Msg = ex.Message;
                return new JsonResult(res);
            }
        }
        #endregion

        #region 重置密码
        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="id"></param>
        /// <param name="updateType"></param>
        /// <returns></returns>
        public async Task<IActionResult> UpdatePwd(long id)
        {
            Mt5User data = await _context.Mt5Users.FindAsync(id);
            if (data == null)
            {
                return NotFound();
            }
            return View(data);
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="id"></param>
        /// <param name="updateType"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<JsonResult> UpdatePwd(ulong id, string updateType)
        {
            Result res = new Result();
            try
            {
                Mt5User user = _context.Mt5Users.Find((long)id);
                if (user == null)
                {
                    res.Code = 1;
                    res.Data = "updateFailed";
                    return new JsonResult(res);
                }
                CrmUser crmUser = _context.CrmUsers.Find(user.CrmId);
                if (crmUser == null)
                {
                    res.Code = 1;
                    res.Data = "updateFailed";
                    return new JsonResult(res);
                }
                if (string.IsNullOrEmpty(crmUser.Email))
                {
                    res.Code = 1;
                    res.Data = "updateFailed";
                    return new JsonResult(res);
                }
                MT5CommonHelper helper = new MT5CommonHelper();
                bool isUpdate = false;
                string newPwd = CommonHelper.pass(8, "!@#$");
                string pwdType = "交易密码";
                if (updateType == "userPassMain")
                {
                    pwdType = "交易密码";
                    isUpdate = helper.UpdatePassword(id, newPwd, EnUsersPasswords.USER_PASS_MAIN);
                }
                else if (updateType == "userPassInvestor")
                {
                    pwdType = "只读密码";
                    isUpdate = helper.UpdatePassword(id, newPwd, EnUsersPasswords.USER_PASS_INVESTOR);
                }
                if (isUpdate)
                {
                    await NetEmailClient.SendMailByConfig(crmUser.Email, $"重置MT5账号{pwdType}", NetEmailClient.ResetPassword(user.Login, newPwd, pwdType), "");
                    res.Code = 0;
                    res.Data = "updateSuccess";
                }
                else
                {
                    res.Code = 1;
                    res.Data = "updateFailed";
                }
                return new JsonResult(res);
            }
            catch (Exception ex)
            {
                res.Code = 1;
                res.Data = "updateFailed";
                res.Msg = ex.Message;
                return new JsonResult(res);
            }
        }
        #endregion

        #region 删除用户
        /// <summary>
        /// 删除单个用户
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns></returns>
        [HttpPost, ActionName("Delete")]
        public JsonResult Delete(ulong id)
        {
            Result res = new Result();
            try
            {
                Mt5User user = _context.Mt5Users.Find((long)id);
                if (user == null)
                {
                    res.Code = 1;
                    return new JsonResult(res);
                }
                bool isDel = false;
                MT5CommonHelper helper = new MT5CommonHelper();
                //isDel = helper.UserDelete(id);
                if (isDel)
                {
                    //_context.Mt5Users.Remove(user);
                    res.Code = 0;
                    res.Data = _context.SaveChanges();
                }
                else
                {
                    res.Code = 1;
                }
                return new JsonResult(res);
            }
            catch (Exception ex)
            {
                res.Code = 1;
                res.Msg = ex.Message;
                return new JsonResult(res);
            }
        }
        #endregion

        #region 调整账户余额
        /// <summary>
        /// 调整账户余额
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns></returns>
        public IActionResult BalanceAdjustment(string idList)
        {
            ViewBag.idList = idList;
            return View();
        }

        /// <summary>
        /// 批量调整账户余额
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpPost, ActionName("EditBalanceAdjustmentItems")]
        public IActionResult EditBalanceAdjustmentItems(long idList, int operationType, decimal price, string remark)
        {
            Result res = new Result();
            try
            {
                MT5CommonHelper helper = new MT5CommonHelper();
                MTUser tmu = helper.QueryUsers(Convert.ToUInt64(idList));
                double FromAmount = Convert.ToDouble(price);
                string operationTypeKey = $"cashDeposit";
                string operationMode = "systemDeposit";
                if (operationType == 1)
                {
                    if (Convert.ToDecimal(tmu.Balance) < price)
                    {
                        res.Code = 1;
                        res.Data = "balanceInsufficient";
                        return new JsonResult(res);
                    }
                    FromAmount = FromAmount * -1;
                    price = price * -1;
                    operationTypeKey = $"cashOut";
                    operationMode = "systemWithdrawal";
                }
                ulong ticker = 0;
                bool MTRetCode = helper.TradeBalance(_context, Convert.ToUInt64(idList), MTDeal.EnDealAction.DEAL_BALANCE, operationMode, FromAmount, remark, Convert.ToDouble(price), 0, User.LoginName, out ticker);
                if (MTRetCode)
                {
                    tmu = helper.QueryUsers(Convert.ToUInt64(idList));
                    Mt5User mt5User = _context.Mt5Users.Find(idList);
                    mt5User.Balance = Convert.ToDecimal(tmu.Balance);
                    mt5User.UpdateDate = DateTime.Now;
                    _context.SaveChanges();
                    res.Code = 0;
                    res.Data = $"{operationTypeKey}Success";
                }
                else
                {
                    res.Code = 1;
                    res.Data = $"{operationTypeKey}Fail";
                }
                return new JsonResult(res);
            }
            catch (Exception ex)
            {
                res.Code = 1;
                res.Data = $"submitFail";
                res.Msg = ex.Message;
                return new JsonResult(res);
            }
        }
        #endregion
    }
}
